<!--
      使用示例：
        <el-form-item label="头像" prop="avatar">
          <el-tooltip
            class="box-item"
            effect="dark"
            content="点击更换头像"
            placement="top"
          >
          <el-avatar
            :src="form.avatar || noAvatar"
            @click="showAvatarSelection"
            style="cursor: pointer;"
          />
          <el-input v-model="form.avatar" type="hidden"></el-input>
          </el-tooltip>
        </el-form-item>


    <AvatarSelection
        v-model="avatarSelectionVisible"
        :current-avatar="form.avatar"
        @avatar-selected="handleAvatarSelected"
    />

    import AvatarSelection from '@/components/AvatarSelection.vue'

    const avatarSelectionVisible = ref(false)

    // 显示头像选择对话框
    const showAvatarSelection = () => {
      avatarSelectionVisible.value = true
    }

    // 处理头像选择结果
    const handleAvatarSelected = (avatarUrl) => {
      form.avatar = avatarUrl
      // 可以选择是否立即保存到服务器
      // editUserInfo()
    }
-->
<template>
  <el-dialog
    v-model="visible"
    title="头像选择"
    width="90%"
    max-width="800px"
    :close-on-click-modal="false"
    :lock-scroll="true"
    center
    @close="handleClose"
  >
    <div class="avatar-selection">
      <!-- 上传和预览区域 -->
      <div class="upload-preview-section">
        <div class="upload-preview-container">
          <!-- 左侧上传区域 -->
          <div class="upload-section">
            <el-upload
              drag
              :auto-upload="false"
              :show-file-list="false"
              :before-upload="beforeUpload"
              :on-change="handleUploadChange"
              :on-progress="handleUploadProgress"
              :on-success="handleUploadSuccess"
              :on-error="handleUploadError"
              :action="`${BASE_URL}/common/upload`"
              ref="uploadRef"
              accept="image/*"
            >
              <div class="upload-content">
                <div class="upload-icon">
                  <el-icon size="40" color="#9ca3af">
                    <Upload />
                  </el-icon>
                </div>
                <p class="upload-text">点击或拖动图片到此处上传</p>
                <p class="upload-hint">支持JPG、PNG格式，文件大小不超过10MB</p>
              </div>
            </el-upload>
            <div v-if="uploading" class="upload-progress">
              <el-progress :percentage="uploadProgress" :stroke-width="8" status="success" />
            </div>
          </div>

          <!-- 右侧预览区域 -->
          <div class="preview-section">
            <div class="preview-container">
              <div class="preview-item">
                <h4 class="preview-title">方形头像预览</h4>
                <el-avatar :size="100" :src="squarePreview || currentAvatar" :fallback-src="defaultAvatar" shape="square" />
              </div>
              <div class="preview-item">
                <h4 class="preview-title">圆形头像预览</h4>
                <el-avatar :size="100" :src="circularPreview || currentAvatar" :fallback-src="defaultAvatar" shape="circle" />
              </div>
            </div>
            <el-button
              v-if="selectedImage || selectedPresetIndex !== null"
              type="primary"
              class="confirm-btn"
              :disabled="uploading"
              @click="selectedImage ? confirmUpload() : confirmPresetSelection()"
            >
              确认选择
            </el-button>
          </div>
        </div>
      </div>

      <!-- 预设头像库 -->
      <div class="preset-avatars-section">
        <h3 class="section-title">从头像库中选择</h3>
        <div class="preset-grid">
          <div
            v-for="(avatar, index) in presetAvatars"
            :key="index"
            class="preset-avatar-item"
            :class="{ 'selected': selectedPresetIndex === index }"
            @click="selectPresetAvatar(index)"
          >
            <div class="preset-card">
              <el-image class="preset-img" :src="avatar.url" fit="cover"></el-image>
            </div>
            <p class="preset-name">{{ avatar.name }}</p>
          </div>
        </div>
      </div>
    </div>

    <!-- 裁剪头像模态框 -->
    <el-dialog
      v-model="showCropModal"
      title="裁剪头像"
      width="90%"
      max-width="800px"
      :close-on-click-modal="false"
      :lock-scroll="true"
      center
    >
      <div class="crop-modal">
        <div class="crop-container">
          <div class="crop-area">
            <vue-cropper
              ref="cropperRef"
              :img="cropImageSrc"
              :outputSize="option.outputSize"
              :outputType="option.outputType"
              :info="option.info"
              :canScale="option.canScale"
              :autoCrop="option.autoCrop"
              :autoCropWidth="option.autoCropWidth"
              :autoCropHeight="option.autoCropHeight"
              :fixed="option.fixed"
              :fixedNumber="option.fixedNumber"
              :full="option.full"
              :fixedBox="option.fixedBox"
              :canMove="option.canMove"
              :canMoveBox="option.canMoveBox"
              :original="option.original"
              :centerBox="option.centerBox"
              :high="option.high"
              :infoTrue="option.infoTrue"
              :maxImgSize="option.maxImgSize"
              :enlarge="option.enlarge"
              :mode="option.mode"
              :limitMinSize="option.limitMinSize"
              @realTime="realTime"
            />
          </div>
          <div class="crop-preview">
            <div class="preview-item">
              <h4 class="preview-title">方形头像预览</h4>
              <div class="preview-box" :style="previewStyle1">
                <div :style="previews.div">
                  <el-avatar :src="previews.url" :style="previews.img" shape="square"/>
                </div>
              </div>
            </div>
            <div class="preview-item">
              <h4 class="preview-title">圆形头像预览</h4>
              <div class="preview-box circular" :style="previewStyle1">
                <div :style="previews.div">
                  <el-avatar :src="previews.url" :style="previews.img" shape="circle"/>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="crop-actions">
          <el-button @click="cancelCrop">取消</el-button>
          <el-button type="primary" @click="confirmCrop">确认裁剪</el-button>
        </div>
      </div>
    </el-dialog>
  </el-dialog>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Upload } from '@element-plus/icons-vue'
import defaultAvatar from '@/assets/images/avatar.png'
import defaultAvatar1 from '@/assets/images/logo.png'
import OfficeWorkerFemale from '@/assets/images/Office-Worker-Female.png'
import OfficeWorkerMale from '@/assets/images/Office-Worker-Male.png'
import PhDFemale from '@/assets/images/PhD-Female.png'
import PhDMale from '@/assets/images/PhD-Male.png'
import MastersFemale from '@/assets/images/Masters-Female.png'
import MastersMale from '@/assets/images/Masters-Male.png'
import CollegeFemale from '@/assets/images/College-Female.png'
import CollegeMale from '@/assets/images/College-Male.png'
import HighSchoolFemale from '@/assets/images/High-School-Female.png'
import HighSchoolMale from '@/assets/images/High-School-Male.png'
import MiddleSchoolFemale from '@/assets/images/Middle-School-Female.png'
import MiddleSchoolMale from '@/assets/images/Middle-School-Male.png'
import ElementarySchoolFemale from '@/assets/images/Elementary-School-Female.png'
import ElementarySchoolMale from '@/assets/images/Elementary-School-Male.png'

import { VueCropper } from 'vue-cropper'

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  currentAvatar: {
    type: String,
    default: ''
  }
})

const emit = defineEmits(['update:modelValue', 'avatarSelected'])

// 模态框显示状态
const visible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

// 文件上传相关
const fileInputRef = ref()
const uploadRef = ref(null)
const uploading = ref(false)
const uploadProgress = ref(0)
// 标记：当前是否在上传裁剪后的文件，避免 on-change 重新触发裁剪流程
const uploadingCropped = ref(false)
const selectedImage = ref('')
const squarePreview = ref('')
const circularPreview = ref('')

// 裁剪相关
const showCropModal = ref(false)
const cropperRef = ref(null)
const cropImageSrc = ref('')
const previews = ref({})
const previewStyle1 = ref({})

// vue-cropper 配置
const option = ref({
  autoCrop: true, // 是否默认生成截图框
  autoCropHeight: 200, // 默认生成截图框高度
  autoCropWidth: 200, // 默认生成截图框宽度
  canMove: true, // 上传图片是否可以移动
  canScale: true, // 图片是否允许滚轮缩放
  centerBox: false, // 截图框是否被限制在图片里面
  fixed: true, // 是否固定截图框的宽高比例
  fixedBox: false, // 是否固定截图框大小
  fixedNumber: [1, 1], // 截图框的宽高比例([ 宽度 , 高度 ])
  info: false, // 裁剪框的大小信息
  infoTrue: false, // 显示预览图片的宽高信息
  mode: 'contain', // 截图框可拖动时的方向
  original: false, // 上传的图片是否按照原始比例渲染
  outputSize: 1, // 裁剪生成图片的质量
  outputType: 'png', // 裁剪生成图片的格式
  full: false, // 是否输出原图比例的截图
  canMoveBox: true, // 截图框能否拖动
  high: true, // 是否按照设备的dpr 输出等比例图片
  maxImgSize: 2000, // 限制图片最大宽度和高度
  enlarge: 1, // 图片根据截图框输出比例倍数
  limitMinSize: 10 // 裁剪框限制最小区域
})

// 预设头像选择
const selectedPresetIndex = ref(null)

// 预设头像库
const presetAvatars = [
  { name: '系统默认头像1', url: defaultAvatar },
  { name: '系统默认头像2', url: defaultAvatar1 },
  { name: '上班族女生', url: OfficeWorkerFemale },
  { name: '上班族男生', url: OfficeWorkerMale },
  { name: '博士女生', url: PhDFemale },
  { name: '博士男生', url: PhDMale },
  { name: '硕士女生', url: MastersFemale },
  { name: '硕士男生', url: MastersMale },
  { name: '大学生女生', url: CollegeFemale },
  { name: '大学生男生', url: CollegeMale },
  { name: '高中女生', url: HighSchoolFemale },
  { name: '高中男生', url: HighSchoolMale },
  { name: '初中女生', url: MiddleSchoolFemale },
  { name: '初中男生', url: MiddleSchoolMale },
  { name: '小学女生', url: ElementarySchoolFemale },
  { name: '小学男生', url: ElementarySchoolMale },
]

// el-upload: 校验与变更
const beforeUpload = (file) => {
  const isImage = file.type.startsWith('image/')
  const isLt10M = file.size / 1024 / 1024 < 10
  if (!isImage) ElMessage.error('请选择图片文件')
  if (!isLt10M) ElMessage.error('文件大小不能超过10MB')
  return isImage && isLt10M
}

const handleUploadChange = (file) => {
  // 仅在初次选择（status === 'ready'）且不是裁剪上传回填时触发裁剪流程
  if (uploadingCropped.value) return
  if (file && file.status === 'ready' && file.raw) {
    processFile(file.raw)
  }
}

// 处理文件
const processFile = (file) => {
  // 检查文件类型
  if (!file.type.startsWith('image/')) {
    ElMessage.error('请选择图片文件')
    return
  }

  // 检查文件大小 (10MB)
  if (file.size > 10 * 1024 * 1024) {
    ElMessage.error('文件大小不能超过10MB')
    return
  }

  const reader = new FileReader()
  reader.onload = (e) => {
    const result = e.target?.result
    cropImageSrc.value = result
    showCropModal.value = true

    // 清除预设头像选择
    selectedPresetIndex.value = null
  }
  reader.readAsDataURL(file)
}

// 实时预览
const realTime = (data) => {
  previews.value = data
  const h = 0.5

  previewStyle1.value = {
    width: data.w + "px",
    height: data.h + "px",
    overflow: "hidden",
    margin: "0",
    zoom: h
  }
}

// 取消裁剪
const cancelCrop = () => {
  showCropModal.value = false
  cropImageSrc.value = ''
  previews.value = {}
  previewStyle1.value = {}

  // 重置文件输入框，确保可以重复选择同一个文件
  if (fileInputRef.value) {
    fileInputRef.value.value = ''
  }
}

// 确认裁剪：立即开始上传
const confirmCrop = () => {
  if (cropperRef.value) {
    cropperRef.value.getCropData(async (data) => {
      selectedImage.value = data
      squarePreview.value = data
      circularPreview.value = data
      showCropModal.value = false
      // 直接上传裁剪后的图片
      await confirmUpload()
    })
  }
}

const BASE_URL = import.meta.env.VITE_BASE_API

// 确认上传：将裁剪结果交给 el-upload 提交，以便使用原生 on-progress
const confirmUpload = async () => {
  if (!selectedImage.value) return

  const response = await fetch(selectedImage.value)
  const blob = await response.blob()
  const file = new File([blob], 'avatar.png', { type: blob.type || 'image/png' })

  uploading.value = true
  uploadProgress.value = 0
  uploadingCropped.value = true

  // 重置并注入文件到 el-upload，然后提交
  uploadRef.value?.clearFiles?.()
  uploadRef.value?.handleStart?.(file)
  uploadRef.value?.submit?.()
}

// el-upload 进度
const handleUploadProgress = (event) => {
  uploading.value = true
  if (event && typeof event.percent === 'number') {
    uploadProgress.value = Math.round(event.percent)
  }
}

// el-upload 成功
const handleUploadSuccess = (response) => {
  uploading.value = false
  uploadingCropped.value = false
  uploadProgress.value = 100
  if (response && response.data) {
    emit('avatarSelected', response.data)
    visible.value = false
    ElMessage.success('头像上传成功')
    // 清空已上传文件，避免 el-upload 再次触发 change 导致重复裁剪
    uploadRef.value?.clearFiles?.()
  } else {
    ElMessage.error('头像上传失败')
  }
}

// el-upload 失败
const handleUploadError = () => {
  uploading.value = false
  uploadingCropped.value = false
  ElMessage.error('上传失败')
}

// 选择预设头像
const selectPresetAvatar = (index) => {
  selectedPresetIndex.value = index
  selectedImage.value = '' // 清除自定义图片选择

  // 更新预览
  const selectedAvatar = presetAvatars[index]
  squarePreview.value = selectedAvatar.url
  circularPreview.value = selectedAvatar.url
}

// 确认预设头像选择
const confirmPresetSelection = () => {
  if (selectedPresetIndex.value !== null) {
    const selectedAvatar = presetAvatars[selectedPresetIndex.value]
    emit('avatarSelected', selectedAvatar.url)
    visible.value = false
    ElMessage.success('头像选择成功')
  }
}

// 处理对话框关闭
const handleClose = () => {
  resetState()
}

// 重置状态
const resetState = () => {
  selectedImage.value = ''
  squarePreview.value = ''
  circularPreview.value = ''
  selectedPresetIndex.value = null
  showCropModal.value = false
  cropImageSrc.value = ''
  previews.value = {}
  previewStyle1.value = {}

  // 重置文件输入框
  if (fileInputRef.value) {
    fileInputRef.value.value = ''
  }
}

// 监听模态框关闭
watch(() => visible.value, (newVal) => {
  if (!newVal) {
    resetState()
  }
})
</script>

<style scoped>
.avatar-selection {
  max-height: 70vh;
  overflow-y: auto;
}

.upload-preview-section {
  min-height: 200px;
  margin-bottom: 24px;
}

.upload-preview-container {
  display: flex;
  gap: 24px;
}

.upload-section {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.upload-area {
  border: 2px dashed #d1d5db;
  border-radius: 8px;
  padding: 30px 20px;
  text-align: center;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.upload-progress {
  margin-top: 12px;
}

:deep(.upload-progress .el-progress) {
  width: 100%;
}

:deep(.upload-progress .el-progress__text) {
  min-width: 32px;
}

.upload-area:hover {
  border-color: #409eff;
}

.upload-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.upload-icon {
  margin-bottom: 8px;
}

.upload-text {
  font-size: 16px;
  color: #374151;
  margin: 0;
}

.upload-hint {
  font-size: 14px;
  color: #6b7280;
  margin: 0;
}

.preview-section {
  flex: 1;
  padding: 20px;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.preview-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
  flex: 1;
}

.preview-item {
  text-align: center;
}

.preview-title {
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 8px;
  color: #374151;
}

.confirm-btn {
  width: 100%;
  margin-top: 16px;
}

.preset-avatars-section {
  border-top: 1px solid #e5e7eb;
  padding-top: 20px;
}

.section-title {
  font-size: 18px;
  font-weight: 500;
  margin-bottom: 16px;
  color: #374151;
}

.preset-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}

.preset-avatar-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px 8px 12px;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 2px solid transparent;
}

.preset-card {
  max-width: 100%;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.preset-img {
  width: 120px;
  height: 120px;
  border-radius: 8px;
}

.preset-avatar-item.selected {
  border-color: #409eff;
}

.preset-name {
  font-size: 12px;
  color: #6b7280;
  margin-top: 8px;
  text-align: center;
  line-height: 1.2;
}

.crop-modal {
  max-height: 70vh;
}

.crop-container {
  display: flex;
  gap: 20px;
  margin-bottom: 20px;
}

.crop-area {
  flex: 1;
  height: 360px;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  overflow: hidden;
}

.crop-preview {
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 120px;
}

.preview-box {
  width: 80px;
  height: 80px;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid #e5e7eb;
  margin: 0 auto;
}

.preview-box.circular {
  border-radius: 50%;
}

.crop-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding-top: 20px;
  border-top: 1px solid #e5e7eb;
}

@media (max-width: 768px) {
  :deep(.avatar-selection-dialog .el-dialog) {
    width: 90vw;
    max-width: 800px;
    border-radius: 12px;
  }

  :deep(.avatar-selection-dialog .el-dialog__body) {
    padding: 12px 16px 16px;
  }

  .upload-preview-container {
    flex-direction: column;
    gap: 12px;
  }

  .upload-area {
    padding: 16px;
    min-height: 110px;
  }

  .upload-progress {
    margin-top: 10px;
  }

  .preview-section {
    padding: 0;
    border: none;
  }

  .preset-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
  }

  .preset-img {
    width: 120px;
    height: 120px;
  }
}

@media (max-width: 420px) {
  .preset-img {
    width: 108px;
    height: 108px;
  }
}
</style>
